//! 系统监控模块
//! 
//! 提供系统资源监控功能

use serde::{Deserialize, Serialize};
use std::sync::Arc;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use tokio::sync::RwLock;
use anyhow::Result;
use tracing::{debug, info, warn};
use sysinfo::{System, SystemExt, CpuExt, DiskExt, NetworkExt, ProcessExt};

use crate::SystemMonitorConfig;

/// 资源使用情况
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourceUsage {
    /// CPU使用率（百分比）
    pub cpu_usage: f64,
    /// 内存使用率（百分比）
    pub memory_usage: f64,
    /// 磁盘使用率（百分比）
    pub disk_usage: f64,
    /// 网络接收字节数
    pub network_rx_bytes: u64,
    /// 网络发送字节数
    pub network_tx_bytes: u64,
}

/// 系统指标
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemMetrics {
    /// 时间戳
    pub timestamp: u64,
    /// 系统信息
    pub system_info: SystemInfo,
    /// CPU指标
    pub cpu_metrics: CpuMetrics,
    /// 内存指标
    pub memory_metrics: MemoryMetrics,
    /// 磁盘指标
    pub disk_metrics: Vec<DiskMetrics>,
    /// 网络指标
    pub network_metrics: NetworkMetrics,
    /// 进程指标
    pub process_metrics: ProcessMetrics,
}

/// 系统信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemInfo {
    /// 操作系统名称
    pub os_name: String,
    /// 操作系统版本
    pub os_version: String,
    /// 主机名
    pub hostname: String,
    /// 内核版本
    pub kernel_version: String,
    /// 启动时间
    pub boot_time: u64,
}

/// CPU指标
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CpuMetrics {
    /// CPU核心数
    pub core_count: usize,
    /// 总体CPU使用率
    pub overall_usage: f64,
    /// 每个核心的使用率
    pub per_core_usage: Vec<f64>,
    /// CPU频率
    pub frequency: u64,
}

/// 内存指标
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryMetrics {
    /// 总内存（字节）
    pub total_memory: u64,
    /// 已使用内存（字节）
    pub used_memory: u64,
    /// 可用内存（字节）
    pub available_memory: u64,
    /// 内存使用率（百分比）
    pub usage_percentage: f64,
    /// 总交换空间（字节）
    pub total_swap: u64,
    /// 已使用交换空间（字节）
    pub used_swap: u64,
}

/// 磁盘指标
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DiskMetrics {
    /// 磁盘名称
    pub name: String,
    /// 挂载点
    pub mount_point: String,
    /// 文件系统类型
    pub file_system: String,
    /// 总空间（字节）
    pub total_space: u64,
    /// 可用空间（字节）
    pub available_space: u64,
    /// 使用率（百分比）
    pub usage_percentage: f64,
}

/// 网络指标
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NetworkMetrics {
    /// 总接收字节数
    pub total_rx_bytes: u64,
    /// 总发送字节数
    pub total_tx_bytes: u64,
    /// 总接收包数
    pub total_rx_packets: u64,
    /// 总发送包数
    pub total_tx_packets: u64,
    /// 网络接口指标
    pub interfaces: Vec<NetworkInterfaceMetrics>,
}

/// 网络接口指标
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NetworkInterfaceMetrics {
    /// 接口名称
    pub name: String,
    /// 接收字节数
    pub rx_bytes: u64,
    /// 发送字节数
    pub tx_bytes: u64,
    /// 接收包数
    pub rx_packets: u64,
    /// 发送包数
    pub tx_packets: u64,
}

/// 进程指标
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProcessMetrics {
    /// 总进程数
    pub total_processes: usize,
    /// 运行中的进程数
    pub running_processes: usize,
    /// 当前进程的指标
    pub current_process: CurrentProcessMetrics,
}

/// 当前进程指标
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CurrentProcessMetrics {
    /// 进程ID
    pub pid: u32,
    /// 进程名称
    pub name: String,
    /// CPU使用率
    pub cpu_usage: f64,
    /// 内存使用量（字节）
    pub memory_usage: u64,
    /// 虚拟内存使用量（字节）
    pub virtual_memory: u64,
    /// 运行时间（秒）
    pub run_time: u64,
}

/// 系统监控器
pub struct SystemMonitor {
    /// 配置
    config: SystemMonitorConfig,
    /// 系统信息
    system: Arc<RwLock<System>>,
    /// 最新指标
    latest_metrics: Arc<RwLock<Option<SystemMetrics>>>,
    /// 是否运行中
    running: Arc<RwLock<bool>>,
}

impl SystemMonitor {
    /// 创建新的系统监控器
    pub fn new(config: SystemMonitorConfig) -> Self {
        let mut system = System::new_all();
        system.refresh_all();

        Self {
            config,
            system: Arc::new(RwLock::new(system)),
            latest_metrics: Arc::new(RwLock::new(None)),
            running: Arc::new(RwLock::new(false)),
        }
    }

    /// 启动监控
    pub async fn start(&self) -> Result<()> {
        let mut running = self.running.write().await;
        if *running {
            return Ok(());
        }
        *running = true;

        info!("启动系统监控");

        let system = self.system.clone();
        let latest_metrics = self.latest_metrics.clone();
        let running_flag = self.running.clone();
        let config = self.config.clone();

        tokio::spawn(async move {
            let mut interval = tokio::time::interval(Duration::from_secs(30));
            
            while *running_flag.read().await {
                interval.tick().await;
                
                if let Ok(metrics) = Self::collect_system_metrics(&system).await {
                    // 检查阈值并记录警告
                    Self::check_thresholds(&metrics, &config).await;
                    
                    // 更新最新指标
                    *latest_metrics.write().await = Some(metrics);
                }
            }
        });

        Ok(())
    }

    /// 停止监控
    pub async fn stop(&self) -> Result<()> {
        let mut running = self.running.write().await;
        *running = false;
        info!("停止系统监控");
        Ok(())
    }

    /// 获取最新指标
    pub async fn get_metrics(&self) -> Result<SystemMetrics> {
        // 如果没有缓存的指标，立即收集一次
        {
            let metrics = self.latest_metrics.read().await;
            if let Some(ref metrics) = *metrics {
                return Ok(metrics.clone());
            }
        }

        // 收集新的指标
        let metrics = Self::collect_system_metrics(&self.system).await?;
        *self.latest_metrics.write().await = Some(metrics.clone());
        Ok(metrics)
    }

    /// 获取资源使用情况
    pub async fn get_resource_usage(&self) -> Result<ResourceUsage> {
        let metrics = self.get_metrics().await?;
        
        Ok(ResourceUsage {
            cpu_usage: metrics.cpu_metrics.overall_usage,
            memory_usage: metrics.memory_metrics.usage_percentage,
            disk_usage: metrics.disk_metrics.iter()
                .map(|d| d.usage_percentage)
                .fold(0.0, f64::max),
            network_rx_bytes: metrics.network_metrics.total_rx_bytes,
            network_tx_bytes: metrics.network_metrics.total_tx_bytes,
        })
    }

    /// 收集系统指标
    async fn collect_system_metrics(system: &Arc<RwLock<System>>) -> Result<SystemMetrics> {
        let mut sys = system.write().await;
        sys.refresh_all();

        let timestamp = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_secs();

        // 系统信息
        let system_info = SystemInfo {
            os_name: sys.name().unwrap_or_else(|| "Unknown".to_string()),
            os_version: sys.os_version().unwrap_or_else(|| "Unknown".to_string()),
            hostname: sys.host_name().unwrap_or_else(|| "Unknown".to_string()),
            kernel_version: sys.kernel_version().unwrap_or_else(|| "Unknown".to_string()),
            boot_time: sys.boot_time(),
        };

        // CPU指标
        let cpus = sys.cpus();
        let cpu_metrics = CpuMetrics {
            core_count: cpus.len(),
            overall_usage: sys.global_cpu_info().cpu_usage() as f64,
            per_core_usage: cpus.iter().map(|cpu| cpu.cpu_usage() as f64).collect(),
            frequency: cpus.first().map(|cpu| cpu.frequency()).unwrap_or(0),
        };

        // 内存指标
        let total_memory = sys.total_memory();
        let used_memory = sys.used_memory();
        let memory_metrics = MemoryMetrics {
            total_memory,
            used_memory,
            available_memory: sys.available_memory(),
            usage_percentage: if total_memory > 0 {
                (used_memory as f64 / total_memory as f64) * 100.0
            } else {
                0.0
            },
            total_swap: sys.total_swap(),
            used_swap: sys.used_swap(),
        };

        // 磁盘指标
        let disk_metrics: Vec<DiskMetrics> = sys.disks().iter().map(|disk| {
            let total_space = disk.total_space();
            let available_space = disk.available_space();
            let used_space = total_space - available_space;
            
            DiskMetrics {
                name: disk.name().to_string_lossy().to_string(),
                mount_point: disk.mount_point().to_string_lossy().to_string(),
                file_system: String::from_utf8_lossy(disk.file_system()).to_string(),
                total_space,
                available_space,
                usage_percentage: if total_space > 0 {
                    (used_space as f64 / total_space as f64) * 100.0
                } else {
                    0.0
                },
            }
        }).collect();

        // 网络指标
        let networks = sys.networks();
        let mut total_rx_bytes = 0;
        let mut total_tx_bytes = 0;
        let mut total_rx_packets = 0;
        let mut total_tx_packets = 0;
        let mut interfaces = Vec::new();

        for (interface_name, data) in networks {
            let rx_bytes = data.received();
            let tx_bytes = data.transmitted();
            let rx_packets = data.packets_received();
            let tx_packets = data.packets_transmitted();

            total_rx_bytes += rx_bytes;
            total_tx_bytes += tx_bytes;
            total_rx_packets += rx_packets;
            total_tx_packets += tx_packets;

            interfaces.push(NetworkInterfaceMetrics {
                name: interface_name.clone(),
                rx_bytes,
                tx_bytes,
                rx_packets,
                tx_packets,
            });
        }

        let network_metrics = NetworkMetrics {
            total_rx_bytes,
            total_tx_bytes,
            total_rx_packets,
            total_tx_packets,
            interfaces,
        };

        // 进程指标
        let processes = sys.processes();
        let total_processes = processes.len();
        let running_processes = processes.values()
            .filter(|p| matches!(p.status(), sysinfo::ProcessStatus::Run))
            .count();

        let current_pid = std::process::id();
        let current_process = processes.get(&sysinfo::Pid::from(current_pid as usize))
            .map(|p| CurrentProcessMetrics {
                pid: current_pid,
                name: p.name().to_string(),
                cpu_usage: p.cpu_usage() as f64,
                memory_usage: p.memory(),
                virtual_memory: p.virtual_memory(),
                run_time: p.run_time(),
            })
            .unwrap_or_else(|| CurrentProcessMetrics {
                pid: current_pid,
                name: "unknown".to_string(),
                cpu_usage: 0.0,
                memory_usage: 0,
                virtual_memory: 0,
                run_time: 0,
            });

        let process_metrics = ProcessMetrics {
            total_processes,
            running_processes,
            current_process,
        };

        Ok(SystemMetrics {
            timestamp,
            system_info,
            cpu_metrics,
            memory_metrics,
            disk_metrics,
            network_metrics,
            process_metrics,
        })
    }

    /// 检查阈值
    async fn check_thresholds(metrics: &SystemMetrics, config: &SystemMonitorConfig) {
        // 检查CPU使用率
        if metrics.cpu_metrics.overall_usage > config.cpu_threshold {
            warn!(
                "CPU使用率过高: {:.2}% > {:.2}%",
                metrics.cpu_metrics.overall_usage,
                config.cpu_threshold
            );
        }

        // 检查内存使用率
        if metrics.memory_metrics.usage_percentage > config.memory_threshold {
            warn!(
                "内存使用率过高: {:.2}% > {:.2}%",
                metrics.memory_metrics.usage_percentage,
                config.memory_threshold
            );
        }

        // 检查磁盘使用率
        for disk in &metrics.disk_metrics {
            if disk.usage_percentage > config.disk_threshold {
                warn!(
                    "磁盘使用率过高 [{}]: {:.2}% > {:.2}%",
                    disk.mount_point,
                    disk.usage_percentage,
                    config.disk_threshold
                );
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_system_monitor_creation() {
        let config = SystemMonitorConfig {
            enabled: true,
            cpu_threshold: 80.0,
            memory_threshold: 85.0,
            disk_threshold: 90.0,
        };

        let monitor = SystemMonitor::new(config);
        // 基本创建测试
        assert!(true); // 如果能创建就说明基本功能正常
    }

    #[tokio::test]
    async fn test_system_metrics_collection() {
        let config = SystemMonitorConfig {
            enabled: true,
            cpu_threshold: 80.0,
            memory_threshold: 85.0,
            disk_threshold: 90.0,
        };

        let monitor = SystemMonitor::new(config);
        let metrics = monitor.get_metrics().await.unwrap();

        // 验证基本指标
        assert!(metrics.timestamp > 0);
        assert!(!metrics.system_info.os_name.is_empty());
        assert!(metrics.cpu_metrics.core_count > 0);
        assert!(metrics.memory_metrics.total_memory > 0);
        assert!(metrics.process_metrics.total_processes > 0);
    }

    #[tokio::test]
    async fn test_resource_usage() {
        let config = SystemMonitorConfig {
            enabled: true,
            cpu_threshold: 80.0,
            memory_threshold: 85.0,
            disk_threshold: 90.0,
        };

        let monitor = SystemMonitor::new(config);
        let usage = monitor.get_resource_usage().await.unwrap();

        // 验证使用率在合理范围内
        assert!(usage.cpu_usage >= 0.0 && usage.cpu_usage <= 100.0);
        assert!(usage.memory_usage >= 0.0 && usage.memory_usage <= 100.0);
        assert!(usage.disk_usage >= 0.0 && usage.disk_usage <= 100.0);
    }
}
